/*
 * llist.h中隐藏数据结构
 * 考虑安全
 * */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "llist.h"

struct llist_node_st
{

	struct llist_node_st *prev;
	struct llist_node_st *next;
	char data[1];
};

struct llist_head_st
{
	int size;
	struct llist_node_st head;

};





/* 创建双向环链的头结点*/
LLIST *llist_create(int initsize)
{
	struct llist_head_st *new;

	new = malloc(sizeof(*new));
	if (new == NULL)
		return NULL;

	new->size = initsize;
	new->head.prev = &(new->head);
	new->head.next = &(new->head);

	return new;
}

/* 插入 头插\尾插*/
int llist_insert(LLIST *p,const void *data,int mode)
{
	struct llist_node_st *newnode;
	struct llist_head_st *ptr = p;/*void * 转 struct llist_head_st */

	newnode = malloc(sizeof(*newnode) + ptr->size);	
	if (newnode == NULL)
		return -1;/* malloc newnode err*/
	
	memcpy(newnode->data,data,ptr->size);
	
	if (mode == LLIST_FORWARD)
	{
		newnode->prev = &(ptr->head);
		newnode->next = ptr->head.next;
	}
	else if (mode == LLIST_BACKWARD)
	{
		newnode->next = &(ptr->head);
		newnode->prev = ptr->head.prev;
	}
	else/*error*/
	{
		return -3;/* func input mode err*/
	}
	newnode->next->prev = newnode;	
	newnode->prev->next = newnode;

	return 0;
}

static struct llist_node_st *find_(struct llist_head_st *ptr,const void *key,llist_cmp *cmp)
{

	struct llist_node_st *cur;

	for(cur = ptr->head.next;cur != &(ptr->head);cur = cur->next)
	{
		if (cmp(key,cur->data) == 0)/*找到了*/
			break;
	}/*没找到返回 ptr->head*/
	
	return cur;

}

void *llist_find(LLIST *p,const void *key,llist_cmp *cmp)
{
	struct llist_node_st *node;
	struct llist_head_st *ptr = p;

	node =  find_(ptr,key,cmp)->data; 
	if (node == &(ptr->head))
		return NULL;
	return node->data;
}


int llist_delete(LLIST *p,const void *key,llist_cmp *cmp)
{
	struct llist_node_st *node;
	struct llist_head_st *ptr = p;

	node = find_(ptr,key,cmp);

	if (node == &(ptr->head))
		return -1;
	node->prev->next = node->next;
	node->next->prev = node->prev;/*脱链*/


	free(node);
	return 0;
}

int llist_fetch(LLIST *p,const void *key,llist_cmp *cmp,void *data)
{
	struct llist_node_st *node;

	struct llist_head_st *ptr = p;

	node = find_(ptr,key,cmp);

	if (node == &(ptr->head))
		return -1;

	node->prev->next = node->next;
	node->next->prev = node->prev;

	if(data != NULL)
		memcpy(data,node->data,ptr->size);

	
	free(node);
	return 0;
}


/* 遍历*/
void llist_travel(LLIST *p,llist_op *op)
{

	struct llist_head_st *ptr = p;
	struct llist_node_st *node = ptr->head.next;


	while(node !=&(ptr->head))
	{
		/*输出：但未知data中数据 解决：使用回调函数(函数地址)*/
		op(node->data);
		node = node->next;
	}
}

/* 销毁*/
void llist_destroy(LLIST *p)
{

	struct llist_head_st *ptr = p;

	struct llist_node_st *cur = ptr->head.next,*temp;
	while(cur!= &(ptr->head))
	{
		temp = cur->next;

		
		free(cur);
		
		cur = temp;
	}/*free 除头结点外的全部结点*/

	free(ptr);
}
